package com.bestv.search.engine.command;

import com.bestv.search.common.cache.SystemCache;
import com.bestv.search.common.dataSource.DataSourceKey;
import com.bestv.search.common.dataSource.DataSourceKeyUtil;
import com.bestv.search.common.model.*;
import com.bestv.search.common.service.InfoManager;
import com.bestv.search.common.util.CharUtil;
import com.bestv.search.common.util.ChineseCharToEn;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.dom4j.Document;
import org.dom4j.Node;

import java.util.Date;
import java.util.List;
import java.util.regex.Pattern;

/**
 * @author Michael Wang
 */

// $Id: HitCommand.java 29 2012-03-13 03:37:49Z wbwang $
public class HitCommand {

    protected final Log log = LogFactory.getLog(getClass());

    private HitQueue hitQueue;
    private HistoryQueue historyQueue;
    private InfoManager infoManager;
    private SystemCache systemCache;

    public void hit(Document doc) {
        SearchKeyword searchKeyword = new SearchKeyword();
        SearchKeywordWrapper wrapper = new SearchKeywordWrapper();
        Node codeNode = doc.selectSingleNode("/request/mediacode");
        if (codeNode == null || "".equals(codeNode.getText().trim())) {
            log.error("Hit request must have a mediacode element.");
            log.error(doc.asXML());
            return;
        }
        wrapper.setMediaCode(codeNode.getText().trim());
        Node keywordNode = doc.selectSingleNode("/request/keyword");
        if (keywordNode == null || "".equals(keywordNode.getText().trim())) {
            log.error("Hit request must have a keyword element.");
            log.error(doc.asXML());
            return;
        }
        searchKeyword.setKeyword(keywordNode.getText().toLowerCase().trim());
        Node userNode = doc.selectSingleNode("/request/userId");
        if (userNode == null || "".equals(userNode.getText().trim())) {
            log.error("Hit request must have a userId element.");
            log.error(doc.asXML());
            return;
        }
        searchKeyword.setUserId(userNode.getText().trim());
        searchKeyword.setHitTime(new Date());
        wrapper.setSearchKeyword(searchKeyword);
        hitQueue.push(wrapper);

        // history operation when hit happens
        History newHistory = transform(wrapper);
        if (newHistory != null)
            historyQueue.push(newHistory);
    }

    private History transform(SearchKeywordWrapper wrapper) {
        History result = new History();
        result.setTime(new Date());
        result.setUserId(wrapper.getSearchKeyword().getUserId());
        String searchKeyword = wrapper.getSearchKeyword().getKeyword();
        String mediaCode, name, actors = "", directors = "";
        // 字母或数字
        String regix = "^\\w+$";
        Pattern pattern = Pattern.compile(regix);
        // 匹配字母或数字时对keyword进行转换
        if (pattern.matcher(searchKeyword).matches()) {
            mediaCode = wrapper.getMediaCode();
            DataSourceKey key = DataSourceKeyUtil.convert(systemCache.getLocalDataSourceKey());
            List<Info> infos = infoManager.getInfoByCode(key, mediaCode);
            Info info = null;
            if (infos == null || infos.size() == 0)
                return null;
            else
                info = infos.get(0);

            name = info.getName();
            // program
            if (info.getType().getId() == 3) {
                actors = ((Program) info).getActors();
                directors = ((Program) info).getDirectors();
            }
            // series
            if (info.getType().getId() == 4) {
                actors = ((Series) info).getActors();
                directors = ((Series) info).getDirectors();
            }
            // schedule
            if (info.getType().getId() == 5) {
                actors = ((Schedule) info).getActors();
                directors = ((Schedule) info).getDirectors();
            }
            name = name + " " + actors + " " + directors;
            searchKeyword = findRealKeywordInStr(name, searchKeyword);
        }
        result.setHistory(searchKeyword);
        return result;
    }

    private String findRealKeywordInStr(String name, String word) {
        String namePY = ChineseCharToEn.getAllFirstLetter(name);
        String nameNum;
        int offset;
        if (namePY.indexOf(word) != -1) {
            offset = namePY.indexOf(word);
            return name.substring(offset, offset + word.length());
        } else {
            nameNum = CharUtil.charToNum(namePY);
            if (nameNum.indexOf(word) != -1) {
                offset = nameNum.indexOf(word);
                return name.substring(offset, offset + word.length());
            }
        }
        return "";
    }

    public List<SearchKeywordWrapper> hitKeywordList() {
        return hitQueue.getHitKeywordList();
    }

    public void clear() {
        hitQueue.clear();
    }

    public void lockQueue() {
        hitQueue.setFirstLevelLock(true);
    }

    public void freeQueue() {
        hitQueue.setFirstLevelLock(false);
    }

    public HitQueue getHitQueue() {
        return hitQueue;
    }

    public void setHitQueue(HitQueue hitQueue) {
        this.hitQueue = hitQueue;
    }

    public HistoryQueue getHistoryQueue() {
        return historyQueue;
    }

    public void setHistoryQueue(HistoryQueue historyQueue) {
        this.historyQueue = historyQueue;
    }

    public InfoManager getInfoManager() {
        return infoManager;
    }

    public void setInfoManager(InfoManager infoManager) {
        this.infoManager = infoManager;
    }

    public SystemCache getSystemCache() {
        return systemCache;
    }

    public void setSystemCache(SystemCache systemCache) {
        this.systemCache = systemCache;
    }
}
